home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
EnigmA Amiga Run 1996 June
/
EnigmA AMIGA RUN 08 (1996)(G.R. Edizioni)(IT)[!][issue 1996-06][EARSAN CD VII].iso
/
earcd
/
utmisc1
/
chktex.lha
/
chktex
/
Resource.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-04-30
|
13KB
|
483 lines
/*
* ChkTeX v1.4, resource file reader.
* Copyright (C) 1995-96 Jens T. Berger Thielemann
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* Contact the author at:
* Jens Berger
* Spektrumvn. 4
* N-0666 Oslo
* Norway
* E-mail: <jensthi@ifi.uio.no>
*
*
*/
#include "ChkTeX.h"
struct WordList
Silent = {{0L}},
Abbrev = {{0L}},
SlowAbbrev = {{0L}},
Linker = {{0L}},
IJAccent = {{0L}},
Italic = {{0L}},
ItalCmd = {{0L}},
UserWarn = {{0L}},
CmdLine = {{0L}},
PostLink = {{0L}},
WipeArg = {{0L}},
VerbEnvir = {{0L}},
MathEnvir = {{0L}},
MathRoman = {{0L}},
TeXInputs = {{0L}},
HyphDash = {{0L}},
NumDash = {{0L}},
WordDash = {{0L}},
CenterDots = {{0L}},
LowDots = {{0L}},
OutFormat = {{0L}};
struct KeyWord
{
STRPTR Name;
STRPTR *String; /* Either of these are set */
struct WordList
*List;
};
struct KeyWord Keys [] =
{
{"ABBREV", NULL, &Abbrev},
{"CENTERDOTS", NULL, &CenterDots},
{"CMDLINE", NULL, &CmdLine},
{"HYPHDASH", NULL, &HyphDash},
{"IJACCENT", NULL, &IJAccent},
{"ITALIC", NULL, &Italic},
{"LINKER", NULL, &Linker},
{"LOWDOTS", NULL, &LowDots},
{"MATHENVIR", NULL, &MathEnvir},
{"MATHROMAN", NULL, &MathRoman},
{"NUMDASH", NULL, &NumDash},
{"OUTFORMAT", NULL, &OutFormat},
{"POSTLINK", NULL, &PostLink},
{"SILENT", NULL, &Silent},
{"TEXINPUTS", NULL, &TeXInputs},
{"USERWARN", NULL, &UserWarn},
{"VERBENVIR", NULL, &VerbEnvir},
{"WIPEARG", NULL, &WipeArg},
{"WORDDASH", NULL, &WordDash},
{"VERBCLEAR", &VerbClear, NULL},
{NULL, NULL, NULL}
};
/***************************** RESOURCE HANDLING **************************/
enum Token
{
tkEof = 0x01, /* End-of-file */
tkOpen = 0x02, /* { */
tkClose = 0x04, /* } */
tkEqual = 0x08, /* = */
tkWord = 0x10, /* Keyword */
tkItem = 0x20 /* List item */
};
static enum Token Expect;
enum Token ReadWord __PROTO((STRPTR, FILE *));
static ULONG RsrcLine;
/*
* Parses the contents of the `.chktexrc' file.
*
* Either:
*
* Keyword { word1 word2 ... }
*
* Or:
*
* Keyword = word1
*
*/
BOOL ReadRC(const STRPTR Filename)
{
STRPTR String = "";
BOOL Success = FALSE;
FILE *fh;
enum Token Token;
ULONG Counter;
struct WordList
*CurList = NULL; /* Where we'll put the words we find */
STRPTR
*CurStr = NULL;
/* Interpret incoming words as ... */
enum
{
whList, /* List elements */
whSolo, /* Solo elements */
whKey /* Keywords */
} What = whKey;
CurList = NULL;
RsrcLine = 0;
Expect = tkWord | tkEof;
if((fh = fopen(Filename, "r")))
{
do
{
Token = ReadWord(ReadBuffer, fh);
ifn(Expect & Token)
{
switch(Token)
{
case tkItem:
String = "item";
break;
case tkWord:
String = "word";
break;
case tkEqual:
String = "`='";
break;
case tkOpen:
String = "`{'";
break;
case tkClose:
String = "`}'";
break;
case tkEof:
String = "EOF";
break;
}
PrintPrgErr(pmFaultFmt, Filename, RsrcLine, String);
Token = tkEof;
}
switch(Token)
{
case tkWord:
for(Counter = 0;
Keys[Counter].Name;
Counter++)
{
if(!strcasecmp(ReadBuffer, Keys[Counter].Name))
{
if(Keys[Counter].List)
{
Expect = tkOpen;
CurList = Keys[Counter].List;
}
else
{
Expect = tkEqual;
CurStr = Keys[Counter].String;
}
break;
}
}
if(!Keys[Counter].Name)
PrintPrgErr(pmKeyWord, ReadBuffer, Filename);
break;
case tkItem:
switch(What)
{
case whSolo:
ifn(*CurStr = strdup(ReadBuffer))
PrintPrgErr(pmStrDupErr);
What = whKey;
Expect = tkWord | tkEof;
break;
case whList:
InsertWord(ReadBuffer, CurList);
break;
case whKey:
PrintPrgErr(pmAssert);
}
break;
case tkEqual:
What = whSolo;
Expect = tkItem;
break;
case tkOpen:
Expect = tkItem | tkClose;
What = whList;
break;
case tkClose:
Expect = tkWord | tkEof;
What = whKey;
break;
case tkEof:
break;
}
} while(Token != tkEof);
fclose(fh);
}
return(Success);
}
/*
* Reads a token from the `.chktexrc' file. Matches brackets. Uses
* ReadLine().
*/
enum Token ReadWord(STRPTR Buffer, FILE *fh)
{
static
STRPTR String = NULL;
static
UBYTE StatBuf[BUFSIZ];
enum Token Retval = tkEof;
UWORD Chr;
STRPTR Ptr = NULL;
BOOL OnceMore = TRUE, Cont = TRUE;
if(Buffer)
{
do
{
if(!(String && *String))
{
if(fgets(StatBuf, BUFSIZ-1, fh))
String = strip(StatBuf, STRP_RGT);
RsrcLine++;
}
Ptr = Buffer;
if((String = strip(String, STRP_LFT)))
{
switch(Chr = *String)
{
case 0:
case CMNT:
String = NULL;
break;
case QUOTE: /* Quoted argument */
Cont = TRUE;
String++;
while(Cont)
{
switch(Chr = *String++)
{
case 0:
case QUOTE:
Cont = FALSE;
break;
case ESCAPE:
ifn(Chr = MapChars(&String))
break;
/* FALLTHRU */
default:
*Ptr++ = Chr;
}
}
*Ptr = 0;
Retval = tkItem;
OnceMore = FALSE;
break;
case '{':
case '}':
case '=':
#define IFTOK(c, ctxt, tk) if((Chr == c) && (Expect & (ctxt))) \
{ Retval = tk; break; }
OnceMore = FALSE;
String++;
IFTOK('{', tkOpen | tkEqual, tkOpen)
else IFTOK('=', tkOpen | tkEqual, tkEqual)
else IFTOK('}', tkClose, tkClose)
String--;
/* FALLTHRU */
default: /* Non-quoted argument */
OnceMore = FALSE;
if(Expect & tkWord)
{
while(Cont)
{
Chr = *String++;
if(isalpha(Chr))
*Ptr++ = Chr;
else
Cont = FALSE;
}
String--;
Retval = tkWord;
}
else
{
while(Cont)
{
switch(Chr = *String++)
{
case CMNT:
case 0:
String = NULL;
Cont = FALSE;
break;
case ESCAPE:
ifn(Chr = MapChars(&String))
break;
*Ptr++ = Chr;
break;
default:
if(!isspace(Chr))
*Ptr++ = Chr;
else
Cont = FALSE;
}
}
Retval = tkItem;
}
ifn(Buffer[0])
{
PrintPrgErr(pmEmptyToken);
if(*String)
String++;
}
*Ptr = 0;
break;
}
}
else
OnceMore = FALSE;
} while(OnceMore);
}
return(Retval);
}
/*
* Translates escape codes. Give it a pointer to the char after the
* escape char, and we'll return what it maps to.
*/
#define MAP(a,b) case a: Tmp = b; break;
UBYTE MapChars(STRPTR *String)
{
UBYTE Chr, Tmp = 0;
UWORD Cnt;
Chr = *((STRPTR) (*String)++);
switch(tolower(Chr))
{
MAP(QUOTE, QUOTE);
MAP(ESCAPE, ESCAPE);
MAP(CMNT, CMNT);
MAP('n', '\n');
MAP('r', '\r');
MAP('b', '\b');
MAP('t', '\t');
MAP('f', '\f');
MAP('{', '{');
MAP('}', '}');
MAP('=', '=');
MAP(' ', ' ');
case 'x':
Tmp = 0;
for(Cnt = 0; Cnt < 2; Cnt++)
{
if(isxdigit(Chr = *((*String)++)))
{
Chr = toupper(Chr);
Tmp = (Tmp<<4) + Chr;
if(isdigit(Chr))
Tmp -= '0';
else
Tmp -= 'A' - 10;
}
else
{
if(Chr) {
PrintPrgErr(pmNotPSDigit, Chr, "hex");
Tmp = 0;
}
break;
}
}
break;
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7':
Tmp = Chr - '0';
for(Cnt = 0; Cnt < 2; Cnt++)
{
Chr = *((*String)++);
if(within('0',Chr,'7'))
Tmp = (Tmp * 8) + Chr - '0';
else
{
if(Chr)
{
PrintPrgErr(pmNotPSDigit, Chr, "octal");
Tmp = 0;
}
break;
}
}
break;
case 'd':
for(Cnt = 0; Cnt < 3; Cnt++)
{
if(isdigit(Chr = *((*String)++)))
Tmp = (Tmp * 10) + Chr - '0';
else
{
if(Chr)
{
PrintPrgErr(pmNotPSDigit, Chr, "");
Tmp = 0;
}
break;
}
}
break;
default:
PrintPrgErr(pmEscCode, ESCAPE, Chr);
}
return(Tmp);
}